from django.http import Http404
from rest_framework import status
from rest_framework.permissions import IsAuthenticated
from rest_framework.views import APIView

from Person.authenticate import MyJSONWebTokenAuthentication
from Utils.BaseResponse import BaseResponse
from .models.serializers import *


class RemoteOJAPIView(APIView):
    """
    提供远程OJ列表获取和新增功能的API视图
    """

    authentication_classes = [MyJSONWebTokenAuthentication]  # 登录认证
    permission_classes = [IsAuthenticated]  # 配置了权限类，没登录的就没有权限访问了

    def get(self, request, format=None):
        """
         获取所有RemoteOJ对象的信息
         :param request: HTTP请求对象
         :param format: 请求数据格式，默认为None
         :return: 包含所有RemoteOJ对象序列化数据的HTTP响应
         """

        remote_oj_list = RemoteOJ.objects.all()
        serializer = RemoteOJSerializer(remote_oj_list, many=True)
        return BaseResponse(serializer.data, status=status.HTTP_200_OK).success()

    def post(self, request, format=None):
        """
        创建一个新的RemoteOJ对象
        :param request: HTTP请求对象，携带待创建RemoteOJ对象的数据
        :request.data 格式示例:
        {
            "name": "LuoGu",
            "baseurl": "https://www.luogu.com.cn/"
        }
        :return: 若数据有效并成功保存，则返回新创建的RemoteOJ对象序列化数据及201 CREATED状态码；否则返回错误信息及400 BAD REQUEST状态码
        """

        serializer = RemoteOJSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save()
            return BaseResponse(serializer.data, status=status.HTTP_201_CREATED).success()
        return BaseResponse(serializer.errors, status=status.HTTP_400_BAD_REQUEST).fail("不合法的数据")


class RemoteOJDetailAPIView(APIView):
    """
    提供对单个RemoteOJ对象进行查询、更新和删除功能的API视图
    """
    authentication_classes = [MyJSONWebTokenAuthentication]  # 登录认证
    permission_classes = [IsAuthenticated]  # 配置了权限类，没登录的就没有权限访问了

    def check_user_permission(self, remote_oj, request):
        pass

    def get_object(self, pk):
        try:
            return RemoteOJ.objects.get(pk=pk)
        except RemoteOJ.DoesNotExist:
            return Http404

    def get(self, request, pk, format=None):
        """
        获取单个RemoteOJ对象的信息
        :param request: HTTP请求对象
        :param pk: 需要获取的RemoteOJ对象的主键
        :param format: 请求数据格式，默认为None
        :return: 若找到对应的RemoteOJ对象，则返回该对象序列化数据及200 OK状态码；否则返回404 NOT FOUND状态码及错误信息
        """
        try:
            remote_oj = self.get_object(pk)
        except Http404:
            return BaseResponse(status=status.HTTP_404_NOT_FOUND).fail(f"对象不存在,不合法的 pk:{pk}")

        serializer = RemoteOJSerializer(remote_oj)
        return BaseResponse(serializer.data, status=status.HTTP_200_OK).success()

    def put(self, request, pk, format=None):
        """
        更新单个RemoteOJ对象的信息
        :param request: HTTP请求对象，携带待更新的RemoteOJ对象数据
        :param pk: 需要更新的RemoteOJ对象的主键
        :param format: 请求数据格式，默认为None
        :return: 若数据有效并成功更新，则返回更新后的RemoteOJ对象序列化数据及200 OK状态码；否则返回错误信息及400 BAD REQUEST状态码
        """
        try:
            remote_oj = self.get_object(pk)
        except Http404:
            return BaseResponse(status=status.HTTP_404_NOT_FOUND).fail(f"对象不存在,不合法的 pk:{pk}")

        serializer = RemoteOJSerializer(remote_oj, data=request.data)
        if serializer.is_valid():
            serializer.save()
            return BaseResponse(serializer.data, status=status.HTTP_200_OK).success()
        else:
            return BaseResponse(serializer.errors, status=status.HTTP_400_BAD_REQUEST).fail("不合法的数据")

    def delete(self, request, pk, format=None):
        """
        删除单个RemoteOJ对象
        :param request: HTTP请求对象
        :param pk: 需要删除的RemoteOJ对象的主键
        :param format: 请求数据格式，默认为None
        :return: 若删除成功，则返回204 NO CONTENT状态码；否则返回404 NOT FOUND状态码及错误信息
        """
        try:
            remote_oj = self.get_object(pk)
        except Http404:
            return BaseResponse(status=status.HTTP_404_NOT_FOUND).fail(f"对象不存在,不合法的 pk:{pk}")

        remote_oj.delete()
        return BaseResponse(status=status.HTTP_204_NO_CONTENT).success()


# 定义RobotAccount管理的API视图类
class RobotAccountAPIView(APIView):
    """
    提供获取全部RobotAccount对象以及新增RobotAccount对象的功能
    """
    authentication_classes = [MyJSONWebTokenAuthentication]  # 登录认证
    permission_classes = [IsAuthenticated]  # 配置了权限类，没登录的就没有权限访问了

    # GET方法：获取所有RobotAccount对象
    def get(self, request, format=None):
        """
        获取所有已注册的RobotAccount对象
        :param request: HTTP请求对象
        :param format: 请求数据格式，默认为None
        :return: 返回包含所有RobotAccount对象数据的BaseResponse实例，状态码为HTTP_200_OK
        """
        # 获取所有RobotAccount对象
        robot = RobotAccount.objects.all()
        # 使用序列化器将RobotAccount对象列表序列化
        serializers = RobotsAccountSerializer(robot, many=True)
        # 返回序列化后的数据并标记为成功响应
        return BaseResponse(serializers.data, status=status.HTTP_200_OK).success()

    # POST方法：新增一个RobotAccount对象
    def post(self, request, format=None):
        """
        新增一个RobotAccount对象
        :param request: HTTP请求对象，其中包含待新增RobotAccount对象的数据
        :request.data 格式示例
        {
            "username": "2365164682@qq.com",
            "password": "zsdfdfsdf1..",
            "remote_oj": 1,
            "is_active": true
        }
        :return: 如果数据有效并成功保存，则返回新增的RobotAccount对象数据，状态码为HTTP_201_CREATED；
                 否则返回错误信息，状态码为HTTP_400_BAD_REQUEST
        """
        # 初始化并填充RobotAccount序列化器
        serializers = RobotsAccountSerializer(data=request.data)
        # 验证并保存数据
        if serializers.is_valid():
            serializers.save()
            # 数据有效，保存成功，返回新增的RobotAccount对象数据及成功消息
            return BaseResponse(serializers.data, status=status.HTTP_201_CREATED).success()
        # 数据无效，返回错误信息及状态码
        else:
            return BaseResponse(serializers.errors, status=status.HTTP_400_BAD_REQUEST).fail("不合法的数据")


# 定义RobotAccount详情管理的API视图类
class RobotAccountDetailAPIView(APIView):
    """
    提供检索、更新、删除指定RobotAccount对象的功能
    """
    authentication_classes = [MyJSONWebTokenAuthentication]  # 登录认证
    permission_classes = [IsAuthenticated]  # 配置了权限类，没登录的就没有权限访问了

    # 用户权限检查方法（此处未实现具体逻辑）
    def check_user_permissions(self, robot_account, request):
        pass

    # 根据主键获取指定RobotAccount对象
    def get_object(self, pk):
        """
        根据主键查找并返回RobotAccount对象
        :param pk: RobotAccount对象的主键
        :return: 查找到的RobotAccount对象，若找不到则返回Http404异常
        """
        try:
            robot_account = RobotAccount.objects.get(pk=pk)
            return robot_account
        except RobotAccount.DoesNotExist:
            return Http404

    # GET方法：根据主键获取单个RobotAccount对象
    def get(self, request, pk, format=None):
        """
        获取指定主键的RobotAccount对象信息
        :param request: HTTP请求对象
        :param pk: 要获取的RobotAccount对象的主键
        :param format: 请求数据格式，默认为None
        :return: 如果找到指定主键的RobotAccount对象，则返回其序列化数据，状态码为HTTP_200_OK；
                 否则返回状态码为HTTP_404_NOT_FOUND的错误信息
        """
        try:
            # 获取指定主键的RobotAccount对象
            robot_account = self.get_object(pk)
        except Http404:
            # 未找到对应RobotAccount对象，返回错误信息及状态码
            return BaseResponse(status=status.HTTP_404_NOT_FOUND).fail(f"对象不存在,不合法的 pk:{pk}")

        # 序列化并返回RobotAccount对象
        serializers = RobotsAccountSerializer(robot_account)
        return BaseResponse(serializers.data, status=status.HTTP_200_OK).success()

    # PUT方法：根据主键更新单个RobotAccount对象
    def put(self, request, pk, format=None):
        """
        更新指定主键的RobotAccount对象信息
        :param request: HTTP请求对象，其中包含待更新的RobotAccount对象数据
        :param pk: 要更新的RobotAccount对象的主键
        :param format: 请求数据格式，默认为None
        :return: 如果数据有效并成功更新，则返回更新后的RobotAccount对象数据，状态码为HTTP_200_OK；
                 否则返回错误信息，状态码为HTTP_400_BAD_REQUEST
        """
        try:
            # 获取指定主键的RobotAccount对象
            robot_account = self.get_object(pk)
        except Http404:
            # 未找到对应RobotAccount对象，返回错误信息及状态码
            return BaseResponse(status=status.HTTP_404_NOT_FOUND).fail(f"对象不存在,不合法的 pk:{pk}")

        # 更新并验证RobotAccount对象信息
        serializers = RobotsAccountSerializer(robot_account, data=request.data)
        if serializers.is_valid():
            serializers.save()
            # 更新成功，返回更新后的RobotAccount对象数据及成功消息
            return BaseResponse(serializers.data, status=status.HTTP_200_OK).success()
        # 更新失败，返回错误信息及状态码
        else:
            return BaseResponse(serializers.errors, status=status.HTTP_400_BAD_REQUEST).fail("不合法的数据")

    # DELETE方法：根据主键删除单个RobotAccount对象
    def delete(self, request, pk, format=None):
        """
        删除指定主键的RobotAccount对象
        :param request: HTTP请求对象
        :param pk: 要删除的RobotAccount对象的主键
        :param format: 请求数据格式，默认为None
        :return: 成功删除后，返回状态码为HTTP_204_NO_CONTENT的响应；
                 若未找到对应RobotAccount对象，则返回状态码为HTTP_404_NOT_FOUND的错误信息
        """
        try:
            # 获取指定主键的RobotAccount对象
            robot_account = self.get_object(pk)
        except Http404:
            # 未找到对应RobotAccount对象，返回错误信息及状态码
            return BaseResponse(status=status.HTTP_404_NOT_FOUND).fail(f"对象不存在,不合法的 pk:{pk}")

        # 删除RobotAccount对象
        robot_account.delete()
        # 返回成功删除的响应
        return BaseResponse(status=status.HTTP_204_NO_CONTENT).success()
